using System.Collections.Generic;
using System.Diagnostics;

namespace BSGraphics.Research.EvoBoost
{
	internal class TreeNodeParameters<T>
	{
		public double ThresholdOrOutcome { get; set; }

		public List<Sample<T>> Samples { get; set; }

		public List<double> PreviousOutcomes { get; set; }

		public double TotalLoss { get; private set; }

		public bool IsDirty { get; set; }

		public TreeNodeParameters(IEnumerable<Sample<T>> samples, IEnumerable<double> previousOutcomes)
		{
			Debug.Assert(samples != null);
			Debug.Assert(previousOutcomes != null);

			this.Samples = new List<Sample<T>>(samples);
			this.PreviousOutcomes = new List<double>(previousOutcomes);

			this.IsDirty = true;
			this.ThresholdOrOutcome = 0;

			Debug.Assert(this.Samples.Count == this.PreviousOutcomes.Count);
		}

		public TreeNodeParameters<T> Clone()
		{
			TreeNodeParameters<T> clone = new TreeNodeParameters<T>(this.Samples, this.PreviousOutcomes);
			clone.ThresholdOrOutcome = this.ThresholdOrOutcome;
			clone.IsDirty = this.IsDirty;
			clone.TotalLoss = this.TotalLoss;

			return clone;
		}

		public void UpdateTotalLoss(ILossFunction lossFunction)
		{
			this.TotalLoss = 0;
			for (int i = 0; i < this.Samples.Count; ++i)
			{
				this.TotalLoss += lossFunction.Calculate(
					this.Samples[i].Outcome, this.PreviousOutcomes[i] + this.ThresholdOrOutcome);
			}
		}
	}
}